//
//  ViewController.m
//  26-GCD
//
//  Created by dllo on 16/8/18.
//  Copyright © 2016年 DM.C. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *topImage;
@property (weak, nonatomic) IBOutlet UIImageView *bottomImage;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    // 1.GCD: Grand(伟大的) Centeral(中央) DisPatch(调度)
    // 2.GCD的核心概念 队列 ,任务拆分分配到队列中, 系统会自动为我们创建线程和调度
    // 3.GCD中的队列严格遵循FIFO(先进先出)原则
    // 队列分类
    //    1. 串行:DISPATCH_QUEUE_SERIAL / NULL
    //    2. 并发:DISPATCH_QUEUE_CONCURRENT
    // 4.队列的创建
    //    参数1:队列的名字
    //    参数2:队列的类型
    // 串行
//    dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
    // 并发
//    dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrentQueue", DISPATCH_QUEUE_CONCURRENT);
    // 术语:
    // 串行, 一个任务执行完毕再执行下一个
    // 并发, 多个任务同时执行
    
    // 主队列是系统提供的类
    // 主队列是串行
//    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    // 全局队列, 并发.
    //    参数1:调度队列优先级
    //    参数2: 占位参数(未来可能会使用)
//    dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
    // 5.同步, 异步
    // 同步 在当前线程执行任务, 不能开辟线程
    // 异步 在新的线程执行任务, 可以开辟线程
    /*************************** 同步 ***********************/
    // 同步, 串行队列, 不会创建线程
//    [self syncSerialQueue:serialQueue];
    
    // 同步, 并发队列, 在主线程操作, 不会创建新的线程
//    [self syncConcurrentQueue:concurrentQueue];
    
    // 同步, 主线程队列
    // 主线程 同步 主线程 会报错
    // 主线程等待同步操作结束, 同步操作在主线程执行, 互相等待, 导致程序卡死
//    [self syncMainQueue:mainQueue];
    // 同步, 全局队列 不会创建子线程
//    [self syncGlobalQueue:globalQueue];
    /*************************** 异步 ***********************/
    // 异步, 串行队列 创建一条新的线程, 在该线程中执行任务
//    [self asyncSerialQueue:serialQueue];
    // 异步, 并发队列 根据任务决定需要开辟多少线程
//    [self asyncConcurrentQueue:concurrentQueue];
    // 异步, 主队列
//    [self asyncMainQueue:mainQueue];
    // 异步, 全局队列
//    [self asyncGlobalQueue:globalQueue];
    
//    _bottomImage.image = [self downImage:[NSURL URLWithString:@"http://img4.duitang.com/uploads/blog/201602/05/20160205185029_ZKz2A.jpeg"]];
    [self disPatchGroup];
}
- (void)syncSerialQueue:(dispatch_queue_t)serialQueue {
        // block中的内容会追加到队列中
    NSLog(@"同步串行队列执行");
        for (int i = 0; i < 10; i++) {
            dispatch_sync(serialQueue, ^{
                NSLog(@"serial---%d---%@", i, [NSThread currentThread]);
            });
        }
}
- (void)syncConcurrentQueue:(dispatch_queue_t)concurrentQueue {
    NSLog(@"同步并发队列执行");
  
        for (int i = 0; i < 10; i++) {
            dispatch_sync(concurrentQueue, ^{
                NSLog(@"concurrent---%d---%@", i, [NSThread currentThread]);
            });
        }
}
- (void)syncMainQueue:(dispatch_queue_t)mainQueue {
    NSLog(@"同步主队列执行");
    dispatch_sync(mainQueue, ^{
        for (int i = 0; i < 10; i++) {
            NSLog(@"global---%d---%@", i, [NSThread currentThread]);
        }
    });
}
- (void)syncGlobalQueue:(dispatch_queue_t)globalQueue {
    NSLog(@"同步全局队列执行");
   
        for (int i = 0; i < 10; i++) {
            dispatch_sync(globalQueue, ^{
                NSLog(@"global---%d---%@", i, [NSThread currentThread]);
            });
        }
}
#pragma mark - 异步
// 异步串行队列, 创建一个新的线程, 在该线程中执行
- (void)asyncSerialQueue:(dispatch_queue_t)serialQueue {
    // block中的内容会追加到队列中
    NSLog(@"异步串行队列执行");
    for (int i = 0; i < 10; i++) {
        dispatch_async(serialQueue, ^{
            NSLog(@"serial---%d---%@", i, [NSThread currentThread]);
        });
    }
}
- (void)asyncConcurrentQueue:(dispatch_queue_t)concurrentQueue {
    NSLog(@"异步并发队列执行");
        for (int i = 0; i < 10; i++) {
            dispatch_async(concurrentQueue, ^{
                NSLog(@"concurrent---%d---%@", i, [NSThread currentThread]);
            });
        }
}
- (void)asyncMainQueue:(dispatch_queue_t)mainQueue {
    NSLog(@"异步主队列执行");
        for (int i = 0; i < 10; i++) {
            dispatch_async(mainQueue, ^{
                NSLog(@"global---%d---%@", i, [NSThread currentThread]);
            });
        }
}
- (void)asyncGlobalQueue:(dispatch_queue_t)globalQueue {
    NSLog(@"异步全局队列执行");
        for (int i = 0; i < 10; i++) {
            dispatch_async(globalQueue, ^{
                NSLog(@"global---%d---%@", i, [NSThread currentThread]);
            });
        }
}

- (void)disPatchGroup {
    // 创建一个group 组
    //  1>组的创建
    dispatch_group_t group  = dispatch_group_create();
    // 创建一个串行队列
    dispatch_queue_t serialQueue = dispatch_queue_create("serialName", DISPATCH_QUEUE_SERIAL);
    //创建一个并行队列
    dispatch_queue_t concurrent1 = dispatch_queue_create("concurrentName", DISPATCH_QUEUE_CONCURRENT);
    // 2>异步加载串行, 组只有异步
    // 组中添加多个任务
    dispatch_group_async(group, serialQueue, ^{
        NSLog(@"group1 --- %@", [NSThread currentThread]);
    });
    dispatch_group_async(group, concurrent1, ^{
       
        NSLog(@"group2 --- %@", [NSThread currentThread]);
    });
    dispatch_group_async(group, concurrent1, ^{
        
        NSLog(@"group3 --- %@", [NSThread currentThread]);
    });
    // 所有任务都执行完毕, 会调用下列方法
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"所有操作完成时, 执行后续操作, 刷新UI");
    });
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        for (int i = 0; i < 3; i ++)
        {
            dispatch_group_enter(group);
            // 任务代码i 假定任务 是异步执行block回调
            NSLog(@"enter----%d", i);

            // block 回调执行
            dispatch_group_leave(group);
            NSLog(@"leave----%d", i);

            // block 回调执行
        }
    });
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    dispatch_async(dispatch_get_main_queue(), ^{
        // 主线程处理
        NSLog(@"wait----%@", [NSThread currentThread]);
    });
    
}
- (IBAction)clickImageButton:(id)sender {
    
    [self downImage];
}

- (void)downImage {
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
            NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://img4.duitang.com/uploads/blog/201602/05/20160205185029_ZKz2A.jpeg"]];
            UIImage *image = [UIImage imageWithData:data];
            // 返回主线程刷新UI
        dispatch_async(dispatch_get_main_queue(), ^{
            _topImage.image = image;
        });
        
    });
    dispatch_queue_t serial = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);
    
    dispatch_async(serial, ^{
        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://img4.duitang.com/uploads/blog/201602/05/20160205185029_ZKz2A.jpeg"]];
        UIImage *image = [UIImage imageWithData:data];
        // 返回主线程刷新UI
        dispatch_async(dispatch_get_main_queue(), ^{
            _bottomImage.image = image;
        });
        
    });

    
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end
